home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / gdb-4.12 / gdb / i386aix-.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-03  |  7.7 KB  |  339 lines

  1. /* Intel 386 native support.
  2.    Copyright (C) 1988, 1989, 1991, 1992 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "defs.h"
  21. #include "frame.h"
  22. #include "inferior.h"
  23. #include "language.h"
  24. #include "gdbcore.h"
  25.  
  26. #ifdef USG
  27. #include <sys/types.h>
  28. #endif
  29.  
  30. #include <sys/param.h>
  31. #include <sys/dir.h>
  32. #include <signal.h>
  33. #include <sys/user.h>
  34. #include <sys/ioctl.h>
  35. #include <fcntl.h>
  36.  
  37. #include <sys/file.h>
  38. #include <sys/stat.h>
  39.  
  40. #include <stddef.h>
  41. #include <sys/ptrace.h>
  42.  
  43. /* Does AIX define this in <errno.h>?  */
  44. extern int errno;
  45.  
  46. #ifndef NO_SYS_REG_H
  47. #include <sys/reg.h>
  48. #endif
  49.  
  50. #include "ieee-float.h"
  51.  
  52. #include "target.h"
  53.  
  54. extern struct ext_format ext_format_i387;
  55.  
  56. /* this table must line up with REGISTER_NAMES in tm-i386v.h */
  57. /* symbols like 'EAX' come from <sys/reg.h> */
  58. static int regmap[] = 
  59. {
  60.   EAX, ECX, EDX, EBX,
  61.   USP, EBP, ESI, EDI,
  62.   EIP, EFL, CS, SS,
  63.   DS, ES, FS, GS,
  64. };
  65.  
  66. /* blockend is the value of u.u_ar0, and points to the
  67.  * place where GS is stored
  68.  */
  69.  
  70. int
  71. i386_register_u_addr (blockend, regnum)
  72.      int blockend;
  73.      int regnum;
  74. {
  75. #if 0
  76.   /* this will be needed if fp registers are reinstated */
  77.   /* for now, you can look at them with 'info float'
  78.    * sys5 wont let you change them with ptrace anyway
  79.    */
  80.   if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM) 
  81.     {
  82.       int ubase, fpstate;
  83.       struct user u;
  84.       ubase = blockend + 4 * (SS + 1) - KSTKSZ;
  85.       fpstate = ubase + ((char *)&u.u_fpstate - (char *)&u);
  86.       return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM));
  87.     } 
  88.   else
  89. #endif
  90.     return (blockend + 4 * regmap[regnum]);
  91.   
  92. }
  93.  
  94. /* The code below only work on the aix ps/2 (i386-ibm-aix) -
  95.  * mtranle@paris - Sat Apr 11 10:34:12 1992
  96.  */
  97.  
  98. struct env387 
  99. {
  100.   unsigned short control;
  101.   unsigned short r0;
  102.   unsigned short status;
  103.   unsigned short r1;
  104.   unsigned short tag;
  105.   unsigned short r2;
  106.   unsigned long eip;
  107.   unsigned short code_seg;
  108.   unsigned short opcode;
  109.   unsigned long operand;
  110.   unsigned short operand_seg;
  111.   unsigned short r3;
  112.   unsigned char regs[8][10];
  113. };
  114.  
  115. static
  116. print_387_status (status, ep)
  117.      unsigned short status;
  118.      struct env387 *ep;
  119. {
  120.   int i;
  121.   int bothstatus;
  122.   int top;
  123.   int fpreg;
  124.   unsigned char *p;
  125.   
  126.   bothstatus = ((status != 0) && (ep->status != 0));
  127.   if (status != 0) 
  128.     {
  129.       if (bothstatus)
  130.     printf_unfiltered ("u: ");
  131.       print_387_status_word (status);
  132.     }
  133.   
  134.   if (ep->status != 0) 
  135.     {
  136.       if (bothstatus)
  137.     printf_unfiltered ("e: ");
  138.       print_387_status_word (ep->status);
  139.     }
  140.   
  141.   print_387_control_word (ep->control);
  142.   printf_unfiltered ("last exception: ");
  143.   printf_unfiltered ("opcode %s; ", local_hex_string(ep->opcode));
  144.   printf_unfiltered ("pc %s:", local_hex_string(ep->code_seg));
  145.   printf_unfiltered ("%s; ", local_hex_string(ep->eip));
  146.   printf_unfiltered ("operand %s", local_hex_string(ep->operand_seg));
  147.   printf_unfiltered (":%s\n", local_hex_string(ep->operand));
  148.   
  149.   top = 7- ((ep->status >> 11) & 7);
  150.   
  151.   printf_unfiltered ("regno  tag  msb              lsb  value\n");
  152.   for (fpreg = 7; fpreg >= 0; fpreg--) 
  153.     {
  154.       double val;
  155.       
  156.       printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : "  ", fpreg);
  157.       
  158.       switch ((ep->tag >> ((7 - fpreg) * 2)) & 3) 
  159.     {
  160.     case 0: printf_unfiltered ("valid "); break;
  161.     case 1: printf_unfiltered ("zero  "); break;
  162.     case 2: printf_unfiltered ("trap  "); break;
  163.     case 3: printf_unfiltered ("empty "); break;
  164.     }
  165.       for (i = 9; i >= 0; i--)
  166.     printf_unfiltered ("%02x", ep->regs[fpreg][i]);
  167.       
  168.       i387_to_double ((char *)ep->regs[fpreg], (char *)&val);
  169.       printf_unfiltered ("  %#g\n", val);
  170.     }
  171. }
  172.  
  173. static struct env387 core_env387;
  174.  
  175. void
  176. i386_float_info ()
  177. {
  178.   struct env387 fps;
  179.   int fpsaved = 0;
  180.  
  181.   if (inferior_pid)
  182.     {
  183.       char buf[10];
  184.       unsigned short status;
  185.  
  186.       ptrace (PT_READ_FPR, inferior_pid, buf, offsetof(struct env387, status));
  187.       memcpy (&status, buf, sizeof (status));
  188.       fpsaved = status;
  189.     }
  190.   else
  191.     {
  192.       if ((fpsaved = core_env387.status) != 0)
  193.     memcpy(&fps, &core_env387, sizeof(fps));
  194.     }
  195.   
  196.   if (fpsaved == 0) 
  197.     {
  198.       printf_unfiltered ("no floating point status saved\n");
  199.       return;
  200.     }
  201.  
  202.   if (inferior_pid)
  203.     {
  204.       int offset;
  205.       for (offset = 0; offset < sizeof(fps); offset += 10)
  206.     {
  207.       char buf[10];
  208.       ptrace (PT_READ_FPR, inferior_pid, buf, offset);
  209.       memcpy ((char *)&fps.control + offset, buf,
  210.           MIN(10, sizeof(fps) - offset));
  211.     }
  212.     } 
  213.  
  214.   print_387_status (0, (struct env387 *)&fps);
  215. }
  216.  
  217. /* Fetch one register.  */
  218. static void
  219. fetch_register (regno)
  220.      int regno;
  221. {
  222.   char buf[MAX_REGISTER_RAW_SIZE];
  223.   if (regno < FP0_REGNUM)
  224.     *(int *)buf = ptrace (PT_READ_GPR, inferior_pid,
  225.               PT_REG(regmap[regno]), 0, 0);
  226.   else
  227.     ptrace (PT_READ_FPR, inferior_pid, buf,
  228.         (regno - FP0_REGNUM)*10 + offsetof(struct env387, regs));
  229.   supply_register (regno, buf);
  230. }
  231.  
  232. void
  233. fetch_inferior_registers (regno)
  234.      int regno;
  235. {
  236.   if (regno < 0)
  237.     for (regno = 0; regno < NUM_REGS; regno++)
  238.       fetch_register (regno);
  239.   else
  240.     fetch_register (regno);
  241. }
  242.  
  243. /* store one register */
  244. static void
  245. store_register (regno)
  246.      int regno;
  247. {
  248.   char buf[80];
  249.   extern char registers[];
  250.   errno = 0;
  251.   if (regno < FP0_REGNUM)
  252.     ptrace (PT_WRITE_GPR, inferior_pid, PT_REG(regmap[regno]),
  253.         *(int *) ®isters[REGISTER_BYTE (regno)], 0);
  254.   else
  255.     ptrace (PT_WRITE_FPR, inferior_pid, ®isters[REGISTER_BYTE (regno)],
  256.         (regno - FP0_REGNUM)*10 + offsetof(struct env387, regs));
  257.  
  258.   if (errno != 0)
  259.     {
  260.       sprintf (buf, "writing register number %d", regno);
  261.       perror_with_name (buf);
  262.     }
  263. }
  264.  
  265. /* Store our register values back into the inferior.
  266.    If REGNO is -1, do this for all registers.
  267.    Otherwise, REGNO specifies which register (so we can save time).  */
  268. void
  269. store_inferior_registers (regno)
  270.      int regno;
  271. {
  272.   if (regno < 0)
  273.     for (regno = 0; regno < NUM_REGS; regno++)
  274.       store_register (regno);
  275.   else
  276.     store_register (regno);
  277. }
  278.  
  279. #ifndef CD_AX            /* defined in sys/i386/coredump.h */
  280. # define CD_AX    0
  281. # define CD_BX    1
  282. # define CD_CX    2
  283. # define CD_DX    3
  284. # define CD_SI    4
  285. # define CD_DI    5
  286. # define CD_BP    6
  287. # define CD_SP    7
  288. # define CD_FL    8
  289. # define CD_IP    9
  290. # define CD_CS    10
  291. # define CD_DS    11
  292. # define CD_ES    12
  293. # define CD_FS    13
  294. # define CD_GS    14
  295. # define CD_SS    15
  296. #endif
  297.  
  298. /*
  299.  * The order here in core_regmap[] has to be the same as in 
  300.  * regmap[] above.
  301.  */
  302. static int core_regmap[] = 
  303. {
  304.   CD_AX, CD_CX, CD_DX, CD_BX,
  305.   CD_SP, CD_BP, CD_SI, CD_DI,
  306.   CD_IP, CD_FL, CD_CS, CD_SS,
  307.   CD_DS, CD_ES, CD_FS, CD_GS,
  308. };
  309.  
  310. void
  311. fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
  312.      char *core_reg_sect;
  313.      unsigned core_reg_size;
  314.      int which;
  315.      unsigned int reg_addr;    /* ignored */
  316. {
  317.  
  318.   if (which == 0)
  319.     {
  320.       /* Integer registers */
  321.  
  322. #define cd_regs(n) ((int *)core_reg_sect)[n]
  323. #define regs(n) *((int *) ®isters[REGISTER_BYTE (n)])
  324.  
  325.       int i;
  326.       for (i = 0; i < FP0_REGNUM; i++)
  327.     regs(i) = cd_regs(core_regmap[i]);
  328.     }
  329.   else if (which == 2)
  330.     {
  331.       /* Floating point registers */
  332.  
  333.       if (core_reg_size >= sizeof (core_env387))
  334.     memcpy (&core_env387, core_reg_sect, core_reg_size);
  335.       else
  336.     fprintf_unfiltered (gdb_stderr, "Couldn't read float regs from core file\n");
  337.     }
  338. }
  339.